package com.tjvib.view.activity;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.TextView;

import androidx.core.app.NotificationManagerCompat;

import com.bumptech.glide.Glide;
import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.LegendRenderer;
import com.jjoe64.graphview.series.DataPoint;
import com.jjoe64.graphview.series.LineGraphSeries;
import com.tjvib.R;
import com.tjvib.base.BaseActivity;
import com.tjvib.util.FileUtil;
import com.tjvib.util.Manager.UserManager;
import com.tjvib.common.Callback;
import com.tjvib.common.RetryCallback;
import com.tjvib.event.PayResultEvent;
import com.tjvib.presenter.SensorPresenter;
import com.tjvib.sensor.SensorData;
import com.tjvib.util.Manager.AppManager;
import com.tjvib.util.LogUtil;
import com.tjvib.util.PayUtil;
import com.tjvib.util.PressUtil;
import com.tjvib.util.ToastUtil;
import com.tjvib.view.dialog.HintDialog;
import com.tjvib.view.dialog.InputDialog;
import com.tjvib.view.dialog.LoadingDialog;
import com.tjvib.view.fragment.DatasetFragment;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.text.SimpleDateFormat;
import java.util.Date;

import static com.tjvib.Constants.SENSOR_TYPE_LOCAL;
import static com.tjvib.Constants.SENSOR_TYPE_LPMSB2;

public abstract class SensorActivity<T extends SensorPresenter, V extends SensorData> extends BaseActivity<T>
        implements CompoundButton.OnCheckedChangeListener {

    NotificationManagerCompat notificationManager;
    int notificationId = 1;

    ImageView sen_iv_back, sen_iv_set, sen_iv_record;
    TextView sen_tv_tit, sen_tv_record, sen_tv_data, sen_tv_info1, sen_tv_info2;
    RadioButton sen_rb_acc, sen_rb_mag, sen_rb_gyr, sen_rb_lin;
    CheckBox sen_cb_x, sen_cb_y, sen_cb_z;
    GraphView sen_gv_data;
    View sen_v_click;

    int dataSelect = 0;
    boolean isDrawing = false;
    double graph2LastXValue = 4.0D;
    LineGraphSeries<DataPoint> mSeries1 = new LineGraphSeries<>(),
            mSeries2 = new LineGraphSeries<>(),
            mSeries3 = new LineGraphSeries<>();

    public static long switchTime = 0;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventBus.getDefault().register(this);
        notificationManager = NotificationManagerCompat.from(this);

        sen_iv_record = findViewById(R.id.sen_iv_record);

        sen_iv_back = findViewById(R.id.sen_iv_back);
        sen_iv_back.setOnClickListener(v -> AppManager.getInstance().finishActivity());

        sen_iv_set = findViewById(R.id.sen_iv_set);

        sen_v_click = findViewById(R.id.sen_v_click);
        sen_v_click.setOnClickListener(v -> {
            if (!presenter.isBound()) {
                ToastUtil.show("Service not started");
                return;
            }
            if (!presenter.isRecording()) {
//                presenter.checkBalance(); 免费采集
                presenter.startRecording();
                sen_tv_record.setText("停止记录");
                Glide.with(this).load(R.mipmap.pause).into(sen_iv_record);
            } else {
                presenter.stopRecording();
                Glide.with(this).load(R.mipmap.play).into(sen_iv_record);
                sen_tv_record.setText("开始记录");
                showStoreDataDialog();
            }
        });

        sen_tv_tit = findViewById(R.id.sen_tv_tit);
        sen_tv_record = findViewById(R.id.sen_tv_record);
        sen_tv_data = findViewById(R.id.sen_tv_data);
        sen_tv_info1 = findViewById(R.id.sen_tv_info1);
        sen_tv_info2 = findViewById(R.id.sen_tv_info2);

        sen_gv_data = findViewById(R.id.sen_gv_data);

        sen_rb_acc = findViewById(R.id.sen_rb_acc);
        sen_rb_mag = findViewById(R.id.sen_rb_mag);
        sen_rb_gyr = findViewById(R.id.sen_rb_gyr);
        sen_rb_lin = findViewById(R.id.sen_rb_lin);
        sen_cb_x = findViewById(R.id.sen_cb_x);
        sen_cb_y = findViewById(R.id.sen_cb_y);
        sen_cb_z = findViewById(R.id.sen_cb_z);

        sen_rb_acc.setOnCheckedChangeListener(this);
        sen_rb_mag.setOnCheckedChangeListener(this);
        sen_rb_gyr.setOnCheckedChangeListener(this);
        sen_rb_lin.setOnCheckedChangeListener(this);
        sen_cb_x.setOnCheckedChangeListener(this);
        sen_cb_y.setOnCheckedChangeListener(this);
        sen_cb_z.setOnCheckedChangeListener(this);

        PressUtil.setPressChange(this, sen_iv_set, sen_iv_back);
    }

    abstract String getSensorName();

    @Override
    protected boolean initView() {
        return true;
    }

    @Override
    protected boolean initData() {
        return true;
    }

    public void setData(V data) {
        runOnUiThread(() -> {
            setInfoLayoutData(data);
            setImageLayoutData(data);
        });
    }

    abstract void setInfoLayoutData(V data);

    abstract void setImageLayoutData(V data);

    public void clearSeries(){
        switchTime = System.currentTimeMillis();
        removeGraph();
        mSeries1 = new LineGraphSeries<>();
        mSeries2 = new LineGraphSeries<>();
        mSeries3 = new LineGraphSeries<>();
        drawGraph();
    }


    private void showStoreDataDialog() {
        String dataSetType = presenter.getDataSetType();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd_HHmmss");
        String localTime = format.format(new Date(System.currentTimeMillis()));
        String defaultDataSetName = getString(R.string.default_data_set_name, dataSetType, localTime);

        InputDialog inputDialog = new InputDialog(SensorActivity.this);
        dialogs.add(inputDialog);
        inputDialog.showDialog(SensorActivity.this, "数据集命名", "", "默认：" + defaultDataSetName,
                view -> {
                    String tableName = inputDialog.getEtCon().getText().toString().trim();
                    if (tableName.isEmpty()) {
                        tableName = defaultDataSetName;
                    }

                    String[] numbers = new String[]{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
                    for (String number : numbers) {
                        if (tableName.startsWith(number)) {
                            ToastUtil.show("不能以数字开头");
                            return;
                        }
                    }
                    inputDialog.dismiss();
                    dialogs.remove(inputDialog);

                    ProgressDialog progressDialog = new ProgressDialog(this);
                    progressDialog.setMessage("正在上传中");
                    progressDialog.setCanceledOnTouchOutside(false);
                    progressDialog.show();
                    presenter.storeData(tableName, new Callback() {
                        @Override
                        public void onSuccess(String message, String data) {
                            progressDialog.dismiss();
                            LogUtil.d("presenter onSuccess: "+message);
                            ToastUtil.show(message);
                            AppManager.getInstance().finishOtherActivity(MainActivity.class);
                        }

                        @Override
                        public void onFail(String message, String data) {
                            progressDialog.dismiss();
                            LogUtil.d("onFail : " + message);
                            ToastUtil.show(message);
                            AppManager.getInstance().finishOtherActivity(MainActivity.class);
//                            showErrorDialogWithRetry(message, () -> showStoreDataDialog());
                        }

                        @Override
                        public void onError(String message, String data) {
                            progressDialog.dismiss();
                            LogUtil.d("onError: " + message);
                            ToastUtil.show(message);
                            AppManager.getInstance().finishOtherActivity(MainActivity.class);
//                            showErrorDialogFinish(message);
                        }
                    });
                },
                view -> {
                    inputDialog.dismiss();
                    showDiscardDataDialog();
                });
    }

    protected void showDiscardDataDialog() {
        HintDialog hintDialog = new HintDialog(SensorActivity.this);
        dialogs.add(hintDialog);
        hintDialog.showDialog(SensorActivity.this, "警告", "将丢弃已记录数据，是否继续？",
                view -> {
                    presenter.discardData();
                    hintDialog.dismiss();
                    dialogs.remove(hintDialog);
                    for (Dialog d : dialogs) {
                        d.dismiss();
                    }
                    dialogs.clear();
                    AppManager.getInstance().finishOtherActivity(MainActivity.class);
                },
                view -> {
                    hintDialog.dismiss();
                    showStoreDataDialog();
                    AppManager.getInstance().finishOtherActivity(MainActivity.class);
                });
    }

    protected void removeGraph() {
        isDrawing = false;
        sen_gv_data.removeAllSeries();
        sen_cb_x.setChecked(false);
        sen_cb_y.setChecked(false);
        sen_cb_z.setChecked(false);
        sen_cb_x.setEnabled(false);
        sen_cb_y.setEnabled(false);
        sen_cb_z.setEnabled(false);
    }

    void drawGraph() {
        sen_gv_data.getViewport().setXAxisBoundsManual(true);
        sen_gv_data.getViewport().setMinX(0);
        sen_gv_data.getViewport().setMaxX(0.5);
        mSeries1.setThickness(3);
        mSeries2.setThickness(3);
        mSeries3.setThickness(3);
        mSeries1.setColor(Color.BLUE);
        mSeries2.setColor(Color.GREEN);
        mSeries3.setColor(Color.RED);
        sen_gv_data.setBackgroundColor(Color.WHITE);
        mSeries1.setTitle("X");
        mSeries2.setTitle("Y");
        mSeries3.setTitle("Z");
        sen_gv_data.getLegendRenderer().setBackgroundColor(Color.TRANSPARENT);
        sen_gv_data.getLegendRenderer().setVisible(true);
        sen_gv_data.getLegendRenderer().setTextSize(18);
        sen_gv_data.getLegendRenderer().setTextColor(R.color.main_grey_2);
        sen_gv_data.getLegendRenderer().setAlign(LegendRenderer.LegendAlign.TOP);
        sen_gv_data.getGridLabelRenderer().setHorizontalAxisTitle("时间(s)");
        sen_gv_data.getGridLabelRenderer().setVerticalAxisTitle("幅值");
        sen_gv_data.getGridLabelRenderer().setHorizontalAxisTitleTextSize(24);
        sen_gv_data.getGridLabelRenderer().setVerticalAxisTitleTextSize(24);
        sen_cb_x.setChecked(true);
        sen_cb_y.setChecked(true);
        sen_cb_z.setChecked(true);
        sen_cb_x.setEnabled(true);
        sen_cb_y.setEnabled(true);
        sen_cb_z.setEnabled(true);
        isDrawing = true;
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onPayResultEvent(PayResultEvent event) {
        switch (event.getStatus()) {
            case PayResultEvent.STATUS_FAILURE:
                showErrorDialog(event.getMessage());
                break;
            default:
                showHintDialog(event.getMessage());
                break;
        }
    }


    public void showSettingDialog(int curType, DialogInterface.OnClickListener onClickListener) {
        String[] deviceChoose = {};
        if (curType == SENSOR_TYPE_LOCAL)
            deviceChoose = new String[]{"Reset Timestamp", "Set Stream Frequency"};
        else if (curType == SENSOR_TYPE_LPMSB2) {
            deviceChoose = new String[]{"Reset Timestamp", "Set Stream Frequency",
                    "Set Imu ID", "Set Gyro Range", "Set Acc Range", "Set Mag Range",
                    "Set Transmit Data", "Set Filter Mode", "Set Orientation Offset"};
        }

        new AlertDialog.Builder(this)
                .setTitle("选择")
                .setItems(deviceChoose, onClickListener)
                .create()
                .show();
    }
}
